package com.wildworld.coreimpl;

import com.wildworld.core.IMap;
import com.wildworld.core.events.IMapRedrawEventListener;
import com.wildworld.core.properties.MapProperty;
import com.wildworld.core.worldobjects.WorldObject;
import org.apache.commons.collections.Closure;
import org.apache.commons.collections.CollectionUtils;

import java.util.*;

/**
 * @author gzhebrakov
 *         Date: 20.07.12
 *         Time: 21:06
 */
public class WildWorldMapImpl implements IMap {

    private MapProperty property;
    private List<IMapRedrawEventListener> redrawEventListenerList;
    private List<WorldObject> objects;
    private List<WorldObject> waterList;
    private List<WorldObject> herbList;

    public WildWorldMapImpl(MapProperty property){
        this.property = property;
        generateWater();
        generateHerb();
    }

    public WildWorldMapImpl(){

    }

    @Override
    public void setProperty(MapProperty property) {

        if (property == null){
            throw new IllegalArgumentException("property can't be null");
        }

        this.property = property;
    }

    @Override
    public MapProperty getProperty() {
        return property;
    }

    @Override
    public void reDraw(List<WorldObject> objects) {
        emitRedrawEvent();
    }

    @Override
    public List<WorldObject> getWorldObjects() {
        return objects;
    }

    @Override
    public void setWorldObjects(List<WorldObject> objectList) {
        objects = objectList;
    }

    public void addWater(WorldObject water){
        if (waterList == null){
            waterList = new LinkedList<WorldObject>();
        }
        waterList.add(water);
    }

    public List<WorldObject> getWaterList(){
        return waterList;
    }

    public void addHerb(WorldObject herb){
        if (herbList == null){
            herbList = new LinkedList<WorldObject>();
        }
        herbList.add(herb);
    }

    public List<WorldObject> getHerbList(){
        return herbList;
    }

    private void generateWater(){
        int allSquare = property.getWidth() * property.getHeight();
        int resultSquare = (allSquare / 100) * property.getWaterPercent();
        int numOfAreas =  property.getWaterPercent()/3;
        //if (property.getWaterPercent() > 30){


        List<Integer> squareSizes = new ArrayList<Integer>();
        Random r = new Random();
        if (numOfAreas > 1){
            int randPercent = 0;
            int sumSquare = 0;

            for (int i = 0; i < numOfAreas; i++){
                int percent = ((r.nextInt(10 - randPercent))*10)+1;
                int s = (resultSquare/100) * percent;
                sumSquare += s;
                squareSizes.add(s);
                randPercent += percent/10;
            }
            if (sumSquare > 0){
                int addSize = (resultSquare - sumSquare) / numOfAreas;
                for (int i = 0 ; i < numOfAreas; i++){
                    squareSizes.set(i, new Integer(squareSizes.get(i) + addSize));
                }
            }
        }else {
            squareSizes.add(resultSquare);
        }

        int [] squaresl = new int[squareSizes.size()];
        for (int i = 0 ; i < squareSizes.size(); i++){
            squaresl[i] = (int) Math.sqrt(squareSizes.get(i));
        }

        for (int i = 0 ; i < squaresl.length; i++){

            WorldObject wi = new WorldObject();
            wi.setColor(0,0,255);
            wi.setWidth((double)squaresl[i]);
            wi.setHeight((double)squaresl[i]);

            wi.setX((double) r.nextInt((int) (property.getWidth() - wi.getWidth())));
            wi.setY((double) r.nextInt((int) (property.getHeight() - wi.getHeight())));

            addWater(wi);
        }


//        Collections.sort(squareSizes, new Comparator<Integer>() {
//            @Override
//            public int compare(Integer o1, Integer o2) {
//                if (o1 == o2){return 0;}
//                return (o1 > o2) ? -1 : 1;
//            }
//        });

       //int resultSquareSize = resultSquare / numOfAreas;
    }

    private void generateHerb(){

    }

    private boolean isCoordinatesInMap(WorldObject obj){

        return false;
    }

    @Override
    public void addRedrawEventListener(IMapRedrawEventListener listener) {
        if (redrawEventListenerList == null){
            redrawEventListenerList = new LinkedList<IMapRedrawEventListener>();
        }
        redrawEventListenerList.add(listener);
    }

    private void emitRedrawEvent(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                CollectionUtils.forAllDo(redrawEventListenerList, new Closure() {
                    @Override
                    public void execute(Object o) {
                        ((IMapRedrawEventListener)o).redraw(WildWorldMapImpl.this);
                    }
                });
            }
        }).start();
    }
}
